/**
 * Created with CLion.
 * Description: 
 * User: loong
 * Date: 2021/7/19
 * Time: 22:08
 */
//#include "StrBlob.hpp"
#include "String.h"
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
using namespace std;

class Foo
{
public:
    Foo sorted() &&;     //用于可改变的右值
    Foo sorted() const &;//可用于任何类型的Foo

private:
    vector<int> data;
};
//本对象为右值，因此可以原址排序
Foo Foo::sorted() &&
{
    cout << "右值引用版本" << endl;
    sort(data.begin(), data.end());
    return *this;
}

//本对象是const或是一个左值，哪种情况我们都不能对其进行原址排
Foo Foo::sorted() const &
{
    cout << "左值引用版本" << endl;
    Foo ret(*this);
    //拷贝一个副本
    //    return ret.sorted();
    return Foo(*this).sorted();
}

class HasPtr
{
    friend void swap(HasPtr &, HasPtr &);

public:
    HasPtr(const std::string & s = std::string())
        : ps(new std::string(s))
        , i(0)
    {
        cout << "构造函数HasPtr()" << endl;
    }
    HasPtr(const HasPtr & hp)
    {
        cout << "拷贝构造函数X(const HasPtr&)" << endl;
        ps = new string(*hp.ps);//拷贝ps指向的对象，而不是拷贝指针本身;
        i  = hp.i;
    }

    HasPtr & operator=(const HasPtr & rhs)
    {
        cout << "赋值拷贝函数operator=(const HasPtr&)" << endl;
        auto newps = new string(*rhs.ps);//拷贝指针指向的对象
        delete ps;                       //销毁原string

        ps = newps;  //指向新string
        i  = rhs.i;  //使用内置的int赋值
        return *this;//返回一个此对象的引用
    }

    HasPtr(HasPtr && _p) noexcept
        : ps(_p.ps)
        , i(_p.i)
    {
        _p.ps = nullptr;
    }

    HasPtr & operator=(HasPtr rhs)
    {
        swap(*this, rhs);
        return *this;
    }

    ~HasPtr() { delete ps; }

private:
    std::string * ps;
    int           i;
};

inline void swap(HasPtr & lhs, HasPtr & rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps);// swap the pointers, not the string data
    swap(lhs.i, rhs.i);  // swap the int members
}

struct X {
    X() { cout << "构造函数X()" << endl; }
    X(const X &) { cout << "拷贝构造函数X(const X&)" << endl; }
    X & operator=(const X & rhs)
    {
        cout << "拷贝赋值运算符=(const X&)" << endl;
        return *this;
    }
    ~X() { cout << "析构函数~X()" << endl; }
};
X f1(X x)
{
    X s = x;
    return s;
}

void f2(X & X)
{
}

HasPtr f(HasPtr hp)
{
    HasPtr ret = hp;
    return ret;
}

class Employee
{
private:
    static int sn;

public:
    Employee() { mysn = sn++; }
    Employee(const string & s)
    {
        name = s;
        mysn = sn++;
    }
    //为13.19题定义的拷贝构造函数和拷贝赋值运算符
    Employee(Employee & e)
    {
        name = e.name;
        mysn = sn++;
    }
    Employee & operator=(Employee & rhs)
    {
        name = rhs.name;
        return *this;
    }
    const string & get_name() { return name; }
    int            get_mysn() { return mysn; }

private:
    string name;
    int    mysn;
};

int  Employee::sn = 0;
void f(Employee & s)
{
    std::cout << s.get_name() << ":" << s.get_mysn() << std::endl;
}

struct Person {
    string name_;
    string age_;
    string gender_;
};
#define PersonSptr shared_ptr<Person>

class Base
{
public:
    void pub_mem() {};

protected:
    int prot_mem = 0;

private:
    char priv_mem = 'T';
};
struct Pub_Derv : public Base {
    //正确:派生类能访问protected成员
    int f() { return prot_mem; }
    //错误: private成员对于派生类来说是不可访问的
    //char g() { return priv_mem; }
    using Base::prot_mem;
    void memfcn(Base & b)
    {
        b = *this;
        cout << "Pub_Derv" << endl;
    }
};
struct Priv_Derv : private Base {
    // private不影响派生类的访问权限
    int f1() const { return prot_mem; }

    void memfcn(Base & b)
    {
        b = *this;
        cout << "Pub_Derv" << endl;
    }
};
struct Prot_Derv : protected Base {
    int  f2() { return prot_mem; }
    void memfcn(Base & b)
    {
        b = *this;
        cout << "Pub_Derv" << endl;
    }
};
struct Derived_from_Public : public Pub_Derv {
    int  use_base() { return prot_mem; }
    void memfcn(Base & b)
    {
        b = *this;
        cout << "Pub_Derv" << endl;
    }
};
struct Derived_from_Protected : protected Prot_Derv {
    int use_base()
    {
        return prot_mem;
    }
    void memfcn(Base & b)
    {
        b = *this;
        cout << "Pub_Derv" << endl;
    }
};
//struct Derived_from_Private : private Priv_Derv {
//    int use_base()
//    {
//        return prot_mem;
//    }
//    void memfcn(Base & b)
//    {
//        b = *this;
//        cout << "Pub_Derv" << endl;
//    }
//};

template<unsigned N,unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
    return strcmp(p1, p2);
}

template<typename I,typename T>
I myfind(I b,I e,const T & val)
{
    while(b != e && *b != val)
        ++b;
    return b;
}

int main(int argc, char ** argv)
{
    compare("hi","mom");

    vector<int>       vi   = {0, 2, 4, 6, 8, 10};
    std::list<string> ls   = {"Hello", "World", "!"};
    auto              iter = myfind(vi.begin(), vi.end(), 6);
    if(iter == vi.end())
        cout << "can not find 6" << endl;
    else
        cout << "find 6 at position : " << iter - vi.begin() << endl;

    auto iter1 = find(ls.begin(), ls.end(), "mom");
    if(iter1 == ls.end())
        cout << "can not find mom" << endl;
    else
        cout << " found mom" << endl;

    //    Base b;
//    Pub_Derv pubDerv;
//    Priv_Derv privDerv;
//    Prot_Derv protDerv;


    return 0;
}
